package com.app.buss.ui;

import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.app.buss.R;
import com.app.buss.base.BaseActivity;
import com.app.buss.bean.GoogleSignBean;
import com.app.buss.bean.LoginBean;
import com.app.buss.mvp.presenter.ApiStores;
import com.app.buss.mvp.presenter.MainPresenter;
import com.app.buss.mvp.view.IMainView;
import com.app.buss.utils.BaseService;
import com.app.buss.utils.DeviceIdUtil;
import com.app.buss.utils.GlideLoadEngine;
import com.app.buss.utils.StatusBarUtil;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.facebook.appevents.AppEventsLogger;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.messaging.FirebaseMessaging;
import com.paytm.pgsdk.PaytmUtility;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.filter.Filter;
import com.zhihu.matisse.internal.entity.CaptureStrategy;
import com.zhihu.matisse.internal.entity.IncapableCause;
import com.zhihu.matisse.internal.entity.Item;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import butterknife.BindView;
import io.branch.referral.util.BranchEvent;
import io.reactivex.functions.Consumer;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.paytm.pgsdk.TransactionManager.PAYTM_APP_PACKAGE;


public class ForwebActivity extends BaseActivity<MainPresenter> implements IMainView {
    private static final int REQUEST_CODE_CHOOSE_PHOTO_ALBUM = 22;
    private static final String TAG = "ForwebActivity_tag";
    @BindView(R.id.ll_web)
    WebView llWeb;
    @BindView(R.id.app_tool)
    LinearLayout appTool;
    @BindView(R.id.toolbar_title)
    TextView toolbarTitle;
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    private static final int RC_SIGN_IN = 11;
    WebSettings webSettings;
    private GoogleSignInClient mGoogleSignInClient;
    private String url = "https://www.google.com";
    private ValueCallback<Uri[]> valueCallback;
    private boolean isNotFirst;
    private String gaid;
    @Override
    protected MainPresenter createPresenter() {
        return new MainPresenter(this);
    }

    @Override
    protected int bindContent() {
        return R.layout.aty_forweb;
    }

    @Override
    protected void initSome() {
        appTool.setVisibility(View.GONE);
        try {
            FirebaseMessaging.getInstance().getToken()
                    .addOnCompleteListener(new OnCompleteListener<String>() {
                        @Override
                        public void onComplete(@NonNull Task<String> task) {
                            if (!task.isSuccessful()) {
                                Log.e(TAG, "Fetching FCM registration token failed", task.getException());
                                return;
                            }

                            // Get new FCM registration token
                            BaseService.getInstance().token = task.getResult();
                            if (BaseService.getInstance().token != null)
                                Log.e("FCM_TOKEN:", BaseService.getInstance().token);
                            // Log and toast
//                            String msg = getString(R.string.msg_token_fmt, token);
//                            Log.d(TAG, msg);
//                            Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                        }
                    });
            GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(this);
            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestEmail()
                    .build();
            mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
            String ua = "";
            if (getIntent() != null && getIntent().getExtras() != null) {
                url = getIntent().getExtras().getString("url");
                ua = getIntent().getExtras().getString("userAgent");
                String fiedCol = getIntent().getExtras().getString("fieldCol");
                String backgroundCol = getIntent().getExtras().getString("backgroundCol");
                if (backgroundCol != null && !backgroundCol.isEmpty())
                    StatusBarUtil.setStatusBarMode(ForwebActivity.this, fiedCol != null && !fiedCol.isEmpty() && fiedCol.equals("black"), Color.parseColor(backgroundCol));
//            if(fiedCol!=null && !fiedCol.isEmpty()){
//                toolbarTitle.setTextColor(fiedCol.equals("black")?Color.BLACK:Color.WHITE);
//            }
            }
            String agentStr = "ANDROID_AGENT_NATIVE/2.0&#8194;%1$s";
            webSettings = llWeb.getSettings();
            String userAgentString = webSettings.getUserAgentString();
            if (ua.isEmpty()) {
                userAgentString = userAgentString.replace("; wv","");
            } else {
                userAgentString = ua+userAgentString;
            }
            llWeb.addJavascriptInterface(new AndroidInterface(this), "AppJs");
            llWeb.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            webSettings.setJavaScriptEnabled(true);
            webSettings.setUserAgentString(userAgentString);
            webSettings.setDomStorageEnabled(true);
            webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
            webSettings.setSupportZoom(true);//是否可以缩放，默认true
            webSettings.setAllowFileAccess(true);
            webSettings.setRenderPriority(WebSettings.RenderPriority.NORMAL);
            webSettings.setAppCacheEnabled(true);
            webSettings.setAppCachePath(getExternalCacheDir().getPath());
            webSettings.setDatabaseEnabled(true);
            webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
            webSettings.setEnableSmoothTransition(true);
            webSettings.setUseWideViewPort(true);
            webSettings.setLoadWithOverviewMode(true);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                llWeb.setWebContentsDebuggingEnabled(false);
            }

            llWeb.clearHistory();
            llWeb.clearCache(true);
            llWeb.clearFormData();
            llWeb.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            llWeb.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    WebView.HitTestResult result = llWeb.getHitTestResult();
                    if (result != null) {
                        int type = result.getType();
                        if (type == WebView.HitTestResult.IMAGE_TYPE) {
                            //TODO实现长按保存图片
                            showSaveImageDialog(result);
                        }
                    }
                    return false;
                }
            });
            llWeb.setDownloadListener(new DownloadListener() {
                @Override
                public void onDownloadStart(String url, String userAgent, String contentDisposition,
                                            String mimeType, long contentLength) {
                    Uri uri = Uri.parse(url);
                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    if (intent.resolveActivity(getPackageManager()) != null) {
                        startActivity(intent);
                    }
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }
        llWeb.setWebChromeClient(mWebChromeClient);
        llWeb.setWebViewClient(mWebViewClient);
        llWeb.loadUrl(url);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    gaid = DeviceIdUtil.getGoogleAdId(ForwebActivity.this);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private WebChromeClient mWebChromeClient = new WebChromeClient(){
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            valueCallback = filePathCallback;
            initPermission2();
            return true;
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }
    };

    private WebViewClient mWebViewClient=new WebViewClient(){
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            //do you  work
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            initToolBar(view.getTitle());
        }
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler h, SslError e) {
            super.onReceivedSslError(view, h,e);
            h.proceed();
        }

    };



    //图片转成Bitmap数组
    final String[] items = new String[]{"Save Image"};

    private void showSaveImageDialog(WebView.HitTestResult result) {
        //图片转成Bitmap数组
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (which) {
                    case 0:
                        try {
                            url2Bitmap(result.getExtra());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                }
            }
        });
        builder.show();
    }

    private void url2Bitmap(String url) {
        Glide.with(this).asBitmap().load(url).into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                if (resource != null) {
                    saveImageToGallery(ForwebActivity.this, resource);
                } else {
                    toastShow("Picture resource get error!");
                }
            }
        });
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            if (llWeb.canGoBack()) {
                llWeb.goBack();
            } else {
                finish();
            }


            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void saveImageToGallery(Context context, Bitmap bmp) {
        // 首先保存图片 创建文件夹
        File appDir = new File(Environment.getExternalStorageDirectory(), "Option");
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        //图片文件名称
        String fileName = "Option_" + System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (Exception e) {
            Log.e("111", e.getMessage());
            e.printStackTrace();
        }

        // 其次把文件插入到系统图库
        String path = file.getAbsolutePath();
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(), path, fileName, null);
        } catch (FileNotFoundException e) {
            Log.e("333", e.getMessage());
            e.printStackTrace();
        }
        // 最后通知图库更新
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri uri = Uri.fromFile(file);
        intent.setData(uri);
        context.sendBroadcast(intent);
        toastShow("Save success!");
    }

    @Override
    public void getDataSuccess(Object model) {
    }

    @Override
    public void getDataFail(String msg) {
    }

//
//    @Override
//    public boolean onKeyDown(int keyCode, KeyEvent event) {
//        if (mAgentWeb.handleKeyEvent(keyCode, event)) {
//            return true;
//        }
//        return super.onKeyDown(keyCode, event);
//    }
//
//    @Override
//    protected void onPause() {
//        mAgentWeb.getWebLifeCycle().onPause();
//        super.onPause();
//
//    }

    @Override
    protected void onResume() {
//        mAgentWeb.getWebLifeCycle().onResume();
        GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(this);
        super.onResume();
    }

    @Override
    public void onDestroy() {
//        mAgentWeb.getWebLifeCycle().onDestroy();
        super.onDestroy();
    }


    public class AndroidInterface {
        private Handler deliver = new Handler(Looper.getMainLooper());
        private Context mContext;

        public AndroidInterface( Context context) {
            this.mContext = context;
        }



        @JavascriptInterface
        public String isNewEdition() {
            return "true";
        }

        @JavascriptInterface
        public String callMethod(String data) {
            Log.e("callMethod>>>>>>",data);
            try {
                JSONObject dataObj = new JSONObject(data);
                String methodName = dataObj.optString("name");
                JSONObject paraObj = dataObj.optJSONObject("parameter");
                String paraStr = dataObj.optString("parameter");

                switch (methodName) {
                    case GET_DEVICE_ID:
                        return getDeviceId();
                    case OPEN_PAY_TM:
                        openPayTm(paraObj);
                        return null;
                    case GET_GA_ID:
                        return getGaId();
                    case GET_GOOGLE_ID:
                        return  getGoogleId();
                    case IS_CONTAINS_NAME:
                        String param1 = paraObj.optString("param1");
                        String param2 = paraObj.optString("param2");
                        return isContainsName(param1,param2).toString();
                    case TAKE_CHANNEL:
                        return  takeChannel();
                    case TAKE_FCM_PUSH_ID:
                        return takeFCMPushId();
                    case TAKE_PORTRAIT_PICTURE:
                        return takePortraitPicture(paraStr);
                    case TAKE_PUSH_ID:
                        return takePushId();
                    case SHOULD_FORBID_SYS_BACK_PRESS:
                        return shouldForbidSysBackPress(Integer.parseInt(paraStr));
                    case FORBID_BACK_FOR_JS:
//                        forbidBackForJS(Integer.parseInt(paraStr),callbackMethod);
                        int forbid = paraObj.optInt("param1");
                        String method = paraObj.optString("param2");
                        return forbidBackForJS(forbid,method);
                    case OPEN_BROWSER:
                        return openBrowser(paraStr);
                    case OPEN_PURE_BROWSER:
                        return openPureBrowser(paraObj.toString());
                    case OPEN_GOOGLE:
                        return openGoogle(paraObj);
                    case SHOW_TITLE_BAR:
                        return showTitleBar(Boolean.valueOf(paraStr));
                    case IS_APP_INSTALLED:
                        return isAPPInstalled(paraStr);
                    default:
                        return null;
                }
            } catch (JSONException e) {
                return null;
            }
        }

        @JavascriptInterface
        public String getDeviceId() {
            return DeviceIdUtil.getDeviceId(mContext);
        }

        /**
         * 打开paytm
         * 本地有paytm打开应用/没有打开web版 paytm支付(web版)需要新开一个页面
         * @param data  {"textToken":"","orderId":"","mid":"","amount":0.0}
         */
        @JavascriptInterface
        public void openPayTm(JSONObject data) {
            openPay(data);
        }
        /**
         * 获取个推设备id
         */
        @JavascriptInterface
        public String takePushId() {
            //现在只需要空实现
            return "";
        }

        /**
         * 获取fcm 令牌
         */
        @JavascriptInterface
        public String takeFCMPushId() {
            //fcm生成的注册令牌
            return BaseService.getInstance().token;
        }




        /**
         * 获取渠道
         */
        @JavascriptInterface
        public String takeChannel() {
            return "google";
        }

        /**
         * 获取ANDROID_ID
         */
        @JavascriptInterface
        public String getGoogleId() {
            Log.e("11111:::",DeviceIdUtil.getAndroidId(mContext));
            return DeviceIdUtil.getAndroidId(mContext);
        }

        /**
         * 集成branch包的时候已经带有Google Play Service核心jar包
         * 获取gpsadid 谷歌广告id
         */
        public String getGaId() {
            if(TextUtils.isEmpty(gaid)) {
                try {
                    gaid = DeviceIdUtil.getGoogleAdId(ForwebActivity.this);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            Log.e("11111:::",gaid);
            return gaid;
        }

        /**
         * 调取谷歌登录方法
         *
         * @param data {"sign":"","host":"https://bb.skr.today"}
         */

        @JavascriptInterface
        public String openGoogle(JSONObject data) {
//            SharedPreferences sp = getSharedPreferences("config",MODE_PRIVATE);
//            boolean isNotFirst = sp.getBoolean("isNotFirst",false);
            if(data!=null) {
                String str  = data.toString();
                if(!str.isEmpty()) {
                    Log.e("openGoogle>>>>>>",str);
//                webBean = new Gson().fromJson(data, GoogleSignBean.class);
                    String host = data.optString("host");
                    String sign = data.optString("sign");
                    webBean = new GoogleSignBean(sign, host);
                    if (!isNotFirst) {
                        signIn();
                    } else {
                        loginInfoPush(host, sign);
                    }
                }
            }else {
                Toast.makeText(ForwebActivity.this,"data error",Toast.LENGTH_SHORT).show();
            }
            return null;
        }

        /**
         * branch事件统计
         *
         * @param eventName 统计事件名称
         */
        @JavascriptInterface
        public void branchEvent(String eventName) {
            new BranchEvent(eventName)
                    .logEvent(mContext);
        }

        /**
         * branch事件统计
         *
         * @param eventName  统计时间名称
         * @param parameters 自定义统计参数
         */
        @JavascriptInterface
        public void branchEvent(String eventName, String parameters) {
            BranchEvent branchEvent = new BranchEvent(eventName);
            JSONObject obj = null;
            try {
                obj = new JSONObject(parameters);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Bundle bundle = new Bundle();
            Iterator<String> keys = obj != null ? obj.keys() : null;
            if (keys != null) {
                while (keys.hasNext()) {
                    String key = keys.next();
                    String value = obj.optString(key);
                    bundle.putString(key, value);
                    branchEvent.addCustomDataProperty(
                            key,
                            value
                    );
                }
            }
            branchEvent
                    .logEvent(mContext);
        }

        /**
         * branch事件统计
         *
         * @param eventName  统计事件名称
         * @param parameters 自定义统计参数
         * @param alias      事件别名
         */
        @JavascriptInterface
        public void branchEvent(String eventName, String parameters, String alias) {
            BranchEvent branchEvent = new BranchEvent(eventName);
            JSONObject obj = null;
            try {
                obj = new JSONObject(parameters);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if (obj == null)
                return;
            Bundle bundle = new Bundle();
            Iterator<String> keys = obj.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                String value = obj.optString(key);
                bundle.putString(key, value);
                branchEvent.addCustomDataProperty(
                        key,
                        value
                );
            }
            branchEvent
                    .setCustomerEventAlias(alias)
                    .logEvent(mContext);

        }

        /**
         * facebook事件统计
         *
         * @param eventName  事件名称
         * @param valueToSum 计数数值
         * @param parameters 自定义统计参数json{}需要全是String类型
         */
        @JavascriptInterface
        public void facebookEvent(String eventName, Double valueToSum, String parameters) {
            AppEventsLogger logger = AppEventsLogger.newLogger(ForwebActivity.this);
            JSONObject obj = null;
            try {
                obj = new JSONObject(parameters);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if(obj==null)
                return;
            Bundle bundle = new Bundle();
            Iterator<String> keys = obj.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                String value = obj.optString(key);
                bundle.putString(key, value);
            }
            logger.logEvent(eventName, valueToSum, bundle);
        }

        /**
         * facebook事件统计
         *
         * @param eventName  事件名称
         * @param parameters 自定义统计参数json{}需要全是String类型
         */
        @JavascriptInterface
        public void facebookEvent(String eventName, String parameters) {
            AppEventsLogger logger = AppEventsLogger.newLogger(ForwebActivity.this);
            JSONObject obj = null;
            try {
                obj = new JSONObject(parameters);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if(obj==null)
                return;
            Bundle bundle = new Bundle();
            Iterator<String> keys = obj.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                String value = obj.optString(key);
                bundle.putString(key, value);
            }
            logger.logEvent(eventName, bundle);
        }

        /**
         * facebook计数统计
         *
         * @param eventName  事件名称
         * @param valueToSum 计数数值
         */
        @JavascriptInterface
        public void facebookEvent(String eventName, Double valueToSum) {
            AppEventsLogger logger = AppEventsLogger.newLogger(ForwebActivity.this);
            logger.logEvent(eventName, valueToSum);
        }

        /**
         * facebook 计数事件统计
         *
         * @param eventName 事件名称
         */
        @JavascriptInterface
        public void facebookEvent(String eventName) {
            AppEventsLogger logger = AppEventsLogger.newLogger(ForwebActivity.this);
            logger.logEvent(eventName);
        }

        /**
         * firebase事件统计
         */
        @JavascriptInterface
        public void firebaseEvent(String category, String parameters) {
            JSONObject obj = null;
            try {
                obj = new JSONObject(parameters);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if (obj == null)
                return;
            Bundle bundle = new Bundle();
            Iterator<String> keys = obj.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                String value = obj.optString(key);
                bundle.putString(key, value);
            }
            FirebaseAnalytics.getInstance(mContext).logEvent(category, bundle);
        }

        /**
         * 头像获取
         *
         * @param callbackMethod 回传图片时调用H5的方法名
         */
        @JavascriptInterface
        public String takePortraitPicture(String callbackMethod) {
            ForwebActivity.this.callbackMethod = callbackMethod;
//            initPermission();
            initPermission2();
//            takephoto();
            return "";
        }

        /**
         * 是否存在交互方法
         *
         * @param name 方法名
         */
        private boolean isHas;
        @JavascriptInterface
        public Boolean isContainsName(String callbackMethod, String name) {
            String[] methods = new String[]{
                    FORBID_BACK_FOR_JS,GET_DEVICE_ID,GET_GA_ID,GET_GOOGLE_ID,
                    IS_CONTAINS_NAME,OPEN_BROWSER,OPEN_GOOGLE,OPEN_PAY_TM,OPEN_PURE_BROWSER,
                    SHOULD_FORBID_SYS_BACK_PRESS,SHOW_TITLE_BAR,TAKE_CHANNEL,TAKE_FCM_PUSH_ID
                    ,TAKE_PORTRAIT_PICTURE,TAKE_PUSH_ID,IS_APP_INSTALLED
            };
            for(String m : methods){
                isHas = m.equals(name);
                if(isHas)
                    break;
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    WebView webView = llWeb;
                    String javaScript = "javascript:" + callbackMethod + "(' + isHas + ')";
                    webView.evaluateJavascript(javaScript, null);
                }
            });
            return isHas;
        }

        /**
         * 是否禁用系统返回键
         * 1 禁止
         */
        @JavascriptInterface
        public String shouldForbidSysBackPress(int forbid) {
            //WebActivity成员变量记录下是否禁止
            setShouldForbidBackPress(forbid);
            //WebActivity 重写onBackPressed方法 变量为1时禁止返回操作
            return null;
        }

        /**
         * 返回键调用h5控制
         *
         * @param forbid     是否禁止返回键 1 禁止
         * @param methodName 反回时调用的h5方法 例如:detailBack() 不需要时传空串只禁止返回
         */
        @JavascriptInterface
        public String forbidBackForJS(int forbid, String methodName) {
            setShouldForbidBackPress(forbid);
            //同上
            setBackPressJSMethod(methodName);
            //WebActivity成员变量记录下js方法名 在禁止返回时调用js方法
            return null;
        }

        /**
         * 使用手机里面的浏览器打开 url
         *
         * @param url 打开 url
         */
//        @JavascriptInterface
//        public void openBrowser(String url) {
//            Uri uri = Uri.parse(url);
//            Intent intent = new Intent();
//            intent.setAction(Intent.ACTION_VIEW);
//            intent.setData(uri);
//            if (intent.resolveActivity(mContext.getPackageManager()) != null) {
//                mContext.startActivity(intent);
//            }
//        }
        /**
         * 使用手机里面的浏览器打开 url
         * 注：如果是WhatsApp对话跳转，先判断本地是否安装了WhatsApp，
         如果已经安装直接跳转，没有安装再打开浏览器
         *
         * @param url 打开 url
         */
        @JavascriptInterface
        public String openBrowser(String url) {
            if (mContext instanceof ForwebActivity) {
                Uri uri = Uri.parse(url);
                Intent intent = new Intent().setAction(Intent.ACTION_VIEW).setData(uri);
                //判断是否为WhatsApp跳转 且本地已安装
                if (url.contains("https://api.whatsapp.com/") && isAPPInstalled(mContext, "com.whatsapp")) {
                    intent.setPackage("com.whatsapp");
                }
                if (intent.resolveActivity(mContext.getPackageManager()) != null) {
                    mContext.startActivity(intent);
                }
            }
            return null;
        }
        @JavascriptInterface
        public Boolean isAPPInstalled(Context context, String packageName) {
            PackageManager pm = context.getPackageManager();
            List<PackageInfo> pinfo = pm.getInstalledPackages(0);
            for (int i = 0; i < pinfo.size(); i++) {
                if (pinfo.get(i).packageName.equals(packageName)) {
                    return true;
                }
            }
            return false;
        }
        @JavascriptInterface
        public String isAPPInstalled(String packageName) {
            if (packageName == null) {
                return "";
            }
            PackageManager pm = getPackageManager();
            List<PackageInfo> pinfo = pm.getInstalledPackages(0);
            for (int i = 0; i < pinfo.size(); i++) {
                if (pinfo.get(i).packageName.equals(packageName)) {
                    JSONObject jo = new JSONObject();
                    try {
                        jo.put("packageName", packageName);
                        jo.put("versionName", pinfo.get(i).versionName);
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                            jo.put("versionCode", pinfo.get(i).getLongVersionCode());
                        } else {
                            jo.put("versionCode", pinfo.get(i).versionCode);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
//                    Log.e(TAG, "isAppInstalled: jo.toString = $jo");
                    return jo.toString();
                }
            }
            return "";
        }


        /**
         * 打开一个基本配置的web url
         *
         * @param json 打开web传参 选填
         *             {"title":"", 打开时显示的标题
         *             "url":"", 加载的地址
         *             "hasTitleBar":"false", 是否显示标题栏
         *             "rewriteTitle":"true", 是否通过加载的Web重写标题
         *             "stateBarTextColor":"black", 状态栏字体颜色 black|white
         *             "titleTextColor":"#FFFFFF", 标题字体颜色
         *             "titleColor":"#FFFFFF", 标题背景色
         *             "postData":"", webView post方法时需要传参
         *             "html":"", 加载htmlCode,
         *             "webBack":"true", true:web回退|false 直接关闭页面
         *             }
         */
        @JavascriptInterface
        public String openPureBrowser(String json) {
            startActivity(new Intent(ForwebActivity.this, Forweb3Activity.class).putExtra("data",json));
            return null;
        }

        /**
         * 控制显示当前页面是否显示 TitleBar
         * （点击返回键webview 后退）
         *
         * @param visible
         */
        @JavascriptInterface
        public String showTitleBar(boolean visible) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (visible)
                        appTool.setVisibility(View.VISIBLE);
                    else
                        appTool.setVisibility(View.GONE);
                }
            });
            return null;
        }
    }
    private static final int PAYTM_REQUEST_CODE = 3;
    private void openPay(JSONObject payInfo) {
        try {
            if (versionCompare(getPaytmVersion(this), "8.6.0") < 0) {
                Bundle bundle = new Bundle();
                bundle.putDouble("nativeSdkForMerchantAmount", payInfo.optDouble("amount"));
                bundle.putString("orderid", payInfo.optString("orderId"));
                bundle.putString("txnToken", payInfo.optString("textToken"));
                bundle.putString("mid", payInfo.optString("mid"));
                Intent paytmIntent = new Intent();
                paytmIntent.setComponent(new ComponentName(PAYTM_APP_PACKAGE, "net.one97.paytm.AJRJarvisSplash"));
                // You must have to pass hard coded 2 here, Else your transaction would not proceed.
                paytmIntent.putExtra("paymentmode", 2);
                paytmIntent.putExtra("bill", bundle);
                startActivityForResult(paytmIntent, PAYTM_REQUEST_CODE);
            } else {
                Intent paytmIntent = new Intent();
                paytmIntent.setComponent(new ComponentName(
                        PAYTM_APP_PACKAGE,
                        "net.one97.paytm.AJRRechargePaymentActivity"
                ));
                paytmIntent.putExtra("paymentmode", 2);
                paytmIntent.putExtra("enable_paytm_invoke", true);
                paytmIntent.putExtra("paytm_invoke", true);
                paytmIntent.putExtra(
                        "price",
                        payInfo.optDouble("amount")+""
                ); //this is string amount

                paytmIntent.putExtra("nativeSdkEnabled", true);
                paytmIntent.putExtra("orderid", payInfo.optString("orderId"));
                paytmIntent.putExtra("txnToken", payInfo.optString("textToken"));
                paytmIntent.putExtra("mid", payInfo.optString("mid"));
                startActivityForResult(paytmIntent, PAYTM_REQUEST_CODE);
            }
        } catch (ActivityNotFoundException e) {
            StringBuilder postData = new StringBuilder();
            String postUrl =
                    "https://securegw.paytm.in/theia/api/v1/showPaymentPage" + "?mid=" + payInfo.optString("mid") + "&orderId=" + payInfo.optString(
                            "orderId"
                    );
            postData.append("MID=").append(payInfo.optString("mid"))
                    .append("&txnToken=").append(payInfo.optString("textToken"))
                    .append("&ORDER_ID=").append(payInfo.optString("orderId"));
//            if (activity is WebActivity) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    llWeb.postUrl(postUrl, postData.toString().getBytes());
                }
            });
//            }
        }
    }

    private String getPaytmVersion(Context context) {
        PackageManager pm = context.getPackageManager();
        try{
            PackageInfo pkgInfo = pm.getPackageInfo(PAYTM_APP_PACKAGE, PackageManager.GET_ACTIVITIES);
            return pkgInfo.versionName;
        }catch (PackageManager.NameNotFoundException e) {
            PaytmUtility.debugLog("Paytm app not installed");
        }
        return null;
    }

    private static final String PACK_NAME = "com.paytm.pgsdk";//包名

    private static boolean isInstallApp(Context context) {
        final PackageManager packageManager = context.getPackageManager();// 获取packagemanager
        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);// 获取所有已安装程序的包信息
        if (pinfo != null) {
            for (int i = 0; i < pinfo.size(); i++) {
                String pn = pinfo.get(i).packageName.toLowerCase(Locale.ENGLISH);
                if (pn.equals(PACK_NAME)) {
                    return true;
                }
            }
        }
        return false;
    }

    private int versionCompare(String str1, String str2){
        if (TextUtils.isEmpty(str1) || TextUtils.isEmpty(str2)) {
            return 1;
        }
        String[] vals1 = str1.split("\\.");
        String[] vals2 = str2.split("\\.");
        int i = 0;
        //set index to first non-equal ordinal or length of shortest version string
        while (i < vals1.length && i < vals2.length && vals1[i]
                .equalsIgnoreCase(vals2[i])
        ) {
            i++;
        }
        //compare first non-equal ordinal number
        if (i < vals1.length && i < vals2.length) {
            int diff = Integer.valueOf(vals1[i])
                    .compareTo(Integer.valueOf(vals2[i]));
            return Integer.signum(diff);
        }
        //the strings are equal or one string is a substring of the other
        //e.g. "1.2.3" = "1.2.3" or "1.2.3" < "1.2.3.4"
        return Integer.signum(vals1.length - vals2.length);
    }

    //上传图片
    private void takephoto() {
        Matisse.from(this)
                .choose(MimeType.ofImage(), false)
                .capture(true)  // 使用相机，和 captureStrategy 一起使用
                .captureStrategy(new CaptureStrategy(true, "com.ttmall.btwin.ttmall.fileprovider"))
                .theme(R.style.Matisse_Dracula)
                .countable(true)
                .maxSelectable(1)
                .addFilter(new Filter() {
                    @Override
                    protected Set<MimeType> constraintTypes() {
                        return new HashSet<MimeType>() {{
                            add(MimeType.PNG);
                        }};
                    }

                    @Override
                    public IncapableCause filter(Context context, Item item) {
                        try {
                            InputStream inputStream = getContentResolver().openInputStream(item.getContentUri());
                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inJustDecodeBounds = true;
                            BitmapFactory.decodeStream(inputStream, null, options);

                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }


                        return null;
                    }
                })
//                .gridExpectedSize((int) getResources().getDimension(R.dimen.imageSelectDimen))
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                .thumbnailScale(0.87f)
                .imageEngine(new GlideLoadEngine())
                .forResult(REQUEST_CODE_CHOOSE_PHOTO_ALBUM);
    }
    private void initPermission()
    {
        RxPermissions rxPermissions=new RxPermissions(this);
        rxPermissions.request(
                permissions
        ).subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean aBoolean) throws Exception {
                if (aBoolean){
                    takephoto();
                }else{
                    toastShow("Permission Error!");
                }
            }
        });
    }
    private String[] permissions = {Manifest.permission.CAMERA
            ,Manifest.permission.WRITE_EXTERNAL_STORAGE
            , Manifest.permission.READ_EXTERNAL_STORAGE};
    private void initPermission2() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查该权限是否已经获取
            int i = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]);
            int l = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]);
            int m = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]);
            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
            if (i != PackageManager.PERMISSION_GRANTED || l != PackageManager.PERMISSION_GRANTED || m != PackageManager.PERMISSION_GRANTED) {
                startRequestPermission();
            }else {
                takephoto();
            }
        }
    }

    /**
     * 开始提交请求权限
     */
    private void startRequestPermission() {
        ActivityCompat.requestPermissions(this, permissions, 321);
    }
    private String methodName;

    private void setBackPressJSMethod(String methodName) {
        this.methodName = methodName;
    }

    private int forbid;

    private void setShouldForbidBackPress(int forbid) {
        this.forbid = forbid;
    }

    private boolean isCanBack;
    @Override
    public void onBackPressed() {
        if (forbid == 1) {
            if (!TextUtils.isEmpty(methodName)) {
                llWeb.evaluateJavascript("javascript:"+methodName+"()",null);
            }
        } else {
            if(isCanBack) {
                if (!llWeb.canGoBack())
                    super.onBackPressed();
                else
                    llWeb.goBack();
            }else {
                finish();
            }
        }
    }

    private GoogleSignBean webBean;
    private void signIn() {
        if(mGoogleSignInClient!=null) {
            Intent signInIntent = mGoogleSignInClient.getSignInIntent();
            startActivityForResult(signInIntent, RC_SIGN_IN);
//            ActivityCompat.startActivityForResult(ForwebActivity.this, signInIntent, RC_SIGN_IN, new Bundle());
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 321) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    //如果没有获取权限，那么可以提示用户去设置界面--->应用权限开启权限
                    toastShow("to setting your permissions");
                } else {
                    takephoto();
                }
            }
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach
            // a listener.
            try {
                Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
                handleSignInResult(task);
            }catch (Exception e){
                e.printStackTrace();
            }
        }else if(resultCode == RESULT_OK &&data != null&&requestCode == REQUEST_CODE_CHOOSE_PHOTO_ALBUM){
            List<Uri> mSelected = Matisse.obtainResult(data);
            if(valueCallback!=null){
                valueCallback.onReceiveValue(mSelected.toArray(new Uri[0]));
            }
            for (Uri uri : mSelected) {
                callback2Web(uriToBase64(uri));
            }
        }else if(requestCode == PAYTM_REQUEST_CODE && data != null){
            String response = data.getStringExtra("response");
            String message = data.getStringExtra("nativeSdkForMerchantMessage");
            JSONObject jsonObject = null;
            String status = "";
            try {
                jsonObject = new JSONObject(response!=null?response:"{}");
                status = jsonObject.optString("STATUS", "");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if (!TextUtils.isEmpty(status)) {
                Toast.makeText(
                        ForwebActivity.this,
                        status.replace("TXN_", ""),
                        Toast.LENGTH_SHORT
                ).show();
            }
        }
    }
    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            BaseService.getInstance().account = completedTask.getResult(ApiException.class);
            // Signed in successfully, show authenticated UI.
            isNotFirst = true;
            loginInfoPush(webBean.getHost(),webBean.getSign());
//            updateUI(account);
        } catch (ApiException e) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Log.e("signInResult_", "signInResult:failed code=" + e.getStatusCode());
//            updateUI(null);
            toastShow("SignIn Error!"+ e.getStatusCode());
            BaseService.getInstance().account = GoogleSignIn.getLastSignedInAccount(this);
            loginInfoPush(webBean.getHost(),webBean.getSign());
        }catch (Exception e){
            e.printStackTrace();
            toastShow("SignIn Exception!");
            BaseService.getInstance().account = GoogleSignIn.getLastSignedInAccount(this);
            loginInfoPush(webBean.getHost(),webBean.getSign());
        }
    }

    /**
     * WebActivity中的方法
     * 需要将图片转码成base64字符串 压缩
     *
     * @param str
     */
    private String callbackMethod;
    private void callback2Web(String str) {
        if (!TextUtils.isEmpty(callbackMethod)) {
            WebView webView = llWeb;
            StringBuilder builder = new StringBuilder(callbackMethod).append("(");
            builder.append("'").append("data:image/png;base64,").append(str.replaceAll("[\\s*\t\n\r]", "")).append("'");
            builder.append(")");
            String method = builder.toString();
            String javaScript = "javascript:" + method;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                webView.evaluateJavascript(javaScript, null);
            } else {
                webView.loadUrl(javaScript);
            }
        }
    }

    private String uriToBase64(Uri uri) {
        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                baos.flush();
                baos.close();
                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.NO_WRAP);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    private void loginInfoPush(String host,String sign){
        Log.e("host,sign>>>>>>>>>",host+","+sign);
        try {
            Retrofit retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(host.endsWith("/") ? host : host + "/")
                    .build();
            ApiStores service = retrofit.create(ApiStores.class);
            if (BaseService.getInstance().account == null) {
                BaseService.getInstance().account = GoogleSignIn.getLastSignedInAccount(this);
            }
            if (BaseService.getInstance().account != null) {
                String personName = BaseService.getInstance().account.getDisplayName();
//                String personGivenName = account.getGivenName();
//                String personFamilyName = account.getFamilyName();
                String personEmail = BaseService.getInstance().account.getEmail();
                String personId = BaseService.getInstance().account.getId();
//                Uri personPhoto = account.getPhotoUrl();
                Call<LoginBean> call = service.login(personId, personName, personEmail, 1, sign);
                call.enqueue(new Callback<LoginBean>() {
                    @Override
                    public void onResponse(Call<LoginBean> call, Response<LoginBean> response) {
                        //请求成功操作
                        LoginBean bean = response.body();
                        if (bean == null)
                            return;
                        String cookie1 = "token1=" + bean.getData().getToken1() + ";expires=1; path=/";
                        String cookie2 = "token2=" + bean.getData().getToken2() + ";expires=1; path=/";
                        CookieManager.getInstance().setCookie(host, cookie1);
                        CookieManager.getInstance().setCookie(host, cookie2);
                        WebView webView = llWeb;
                        webView.loadUrl(bean.getData().getUrl());
                    }

                    @Override
                    public void onFailure(Call<LoginBean> call, Throwable t) {

                    }
                });
            }else{
                toastShow("Google Info Error!");
            }
        }catch (Exception e){
            e.printStackTrace();
            toastShow("Google Login Exception!");
        }

    }


    public static final String FORBID_BACK_FOR_JS = "forbidBackForJS";
    public static final String GET_DEVICE_ID = "getDeviceId";
    public static final String GET_GA_ID = "getGaId";
    public static final String GET_GOOGLE_ID = "getGoogleId";
    public static final String IS_CONTAINS_NAME = "isContainsName";
    public static final String OPEN_BROWSER = "openBrowser";
    public static final String OPEN_GOOGLE = "openGoogle";
    public static final String OPEN_PAY_TM = "openPayTm";
    public static final String OPEN_PURE_BROWSER = "openPureBrowser";
    public static final String SHOULD_FORBID_SYS_BACK_PRESS = "shouldForbidSysBackPress";
    public static final String SHOW_TITLE_BAR = "showTitleBar";
    public static final String TAKE_CHANNEL = "takeChannel";
    public static final String TAKE_FCM_PUSH_ID = "takeFCMPushId";
    public static final String TAKE_PORTRAIT_PICTURE = "takePortraitPicture";
    public static final String TAKE_PUSH_ID = "takePushId";
    public static final String IS_APP_INSTALLED = "isAppInstalled";

}
